import { Controller, Get, Query, Put, Res } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagger';
import { PointsGoodsExchangeService } from './points-goods-exchange.service';
import {
  PointsGoodsExchangePageDto,
  PointsGoodsExchangeResponseDto,
  PointsGoodsExchangeExportDto,
} from './points-goods-exchange.dto';
import { StandardPagination } from '~/helper/paginate';
import {
  PointsGoodsExchangeEntity,
  PointsGoodsExchangeStatus,
} from './points-goods-exchange.entity';
import { ModuleSwaggerTags } from '~/constants/modules.constant';
import { ExcelService } from '~/modules/tools/excel/excel.service';
import { FastifyReply } from 'fastify';

@ApiTags(ModuleSwaggerTags.POINTS)
@ApiBearerAuth()
@Controller('exchange')
export class PointsGoodsExchangeController {
  constructor(
    private readonly pointsGoodsExchangeService: PointsGoodsExchangeService,
    private readonly excelService: ExcelService
  ) {}

  @Get('page')
  @ApiOperation({ summary: '分页查询积分商品兑换列表' })
  @ApiResponse({
    status: 200,
    description: '查询成功',
    type: StandardPagination<PointsGoodsExchangeResponseDto>,
  })
  async findPage(
    @Query() dto: PointsGoodsExchangePageDto
  ): Promise<StandardPagination<PointsGoodsExchangeEntity>> {
    return await this.pointsGoodsExchangeService.findPage(dto);
  }

  @Get('export')
  @ApiOperation({ summary: '导出积分商品兑换列表' })
  @ApiResponse({
    status: 200,
    description: '导出成功',
    headers: {
      'Content-Type': {
        description: 'Excel文件类型',
        schema: { type: 'string', example: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }
      },
      'Content-Disposition': {
        description: '文件下载头',
        schema: { type: 'string', example: 'attachment; filename="积分兑换.xlsx"' }
      }
    }
  })
  @ApiResponse({
    status: 500,
    description: '导出失败',
    schema: {
      type: 'object',
      properties: {
        statusCode: { type: 'number', example: 500 },
        message: { type: 'string', example: '导出Excel文件失败' },
        error: { type: 'string', example: 'Internal Server Error' }
      }
    }
  })
  async exportExcel(
    @Query() dto: PointsGoodsExchangeExportDto,
    @Res() res: FastifyReply
  ): Promise<void> {
    try {
      // 查询所有符合条件的数据
      const exchangeList = await this.pointsGoodsExchangeService.findAllForExport(dto);

      // 转换数据格式用于Excel导出
			const excelData = exchangeList.map(exchange => {
				console.log(exchange);
				// 使用正则表达式从标题中提取数字
				const titleNumberMatch = exchange?.title?.match(/\d+/);
				const titleNumber = titleNumberMatch ? titleNumberMatch[0] : '';

				return {
					用户名: exchange.user?.wechat?.nickname || exchange.user?.admin?.username || '未知用户',
					商品名称: exchange.goods?.name || '未知商品',
					兑换积分: exchange.goods?.price || 0,
					状态: this.getStatusText(exchange.status),
					兑换时间: exchange.createdAt ? new Date(exchange.createdAt).toLocaleString('zh-CN') : '',
					标题数字: titleNumber
				};
			});

      // 定义Excel列
      const columns = [
        { header: '用户名', key: '用户名', width: 20 },
        { header: '商品名称', key: '商品名称', width: 30 },
        { header: '兑换积分', key: '兑换积分', width: 15 },
        { header: '状态', key: '状态', width: 15 },
        { header: '兑换时间', key: '兑换时间', width: 25 }
      ];

      // 创建Excel工作簿
      const workbook = await this.excelService.createWorkbook('积分兑换记录', columns, excelData);

      // 将工作簿转换为Buffer
      const buffer = await this.excelService.workbookToBuffer(workbook);

      // 设置响应头
      const filename = `积分兑换_${new Date().toISOString().slice(0, 10)}.xlsx`;
      res.header('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
      res.header('Content-Disposition', `attachment; filename="${encodeURIComponent(filename)}"`);

      // 发送文件
      return res.send(buffer);
    } catch (error) {
      return res.status(500).send({
        statusCode: 500,
        message: `导出Excel文件失败: ${error.message}`,
        error: 'Internal Server Error'
      });
    }
  }

  /**
   * 获取状态中文描述
   * @param status 状态枚举值
   * @returns 中文描述
   */
  private getStatusText(status: PointsGoodsExchangeStatus): string {
    const statusMap = {
      [PointsGoodsExchangeStatus.PENDING]: '待处理',
      [PointsGoodsExchangeStatus.APPROVED]: '已处理',
      [PointsGoodsExchangeStatus.COMPLETED]: '已完成',
      [PointsGoodsExchangeStatus.CANCELLED]: '已取消',
      [PointsGoodsExchangeStatus.REJECTED]: '已拒绝'
    };
    return statusMap[status] || '未知状态';
  }

  @Put('status')
  @ApiOperation({ summary: '更新积分商品兑换状态' })
  @ApiResponse({
    status: 200,
    description: '更新成功',
    type: PointsGoodsExchangeResponseDto,
  })
  async updateStatus(
    @Query('id') id: string,
    @Query('status') status: string
  ): Promise<void> {
    if (!Object.values(PointsGoodsExchangeStatus).includes(status as any)) {
      throw new Error(
        `Invalid status: ${status}. Must be one of: ${Object.values(PointsGoodsExchangeStatus).join(
          ', '
        )}`
      );
    }

    await this.pointsGoodsExchangeService.updateStatus(parseInt(id), status as PointsGoodsExchangeStatus);
  }
}
